home *** CD-ROM | disk | FTP | other *** search
-
-
- #include <Picker.h>
-
-
- /*
- * (NX, NY, NZ) is the light source vector -- length should be
- * 100
- */
- #define NX 48
- #define NY (-36)
- #define NZ 80
- #define NR 100
-
- #define MIN(a,b) ( ( (a) < (b) ) ? (a) : (b) )
-
- #define LIMIT_RADIUS
-
- #ifdef LIMIT_RADIUS
- #include <math.h>
- #define SQRT sqrt
- #else // was testing other sq_root functions
- int ISqrt(register int n);
- #define SQRT ISqrt
- #endif
-
- int errno;
-
- typedef struct {
- Rect r;
- int width, height;
- int radius;
- int x0; /* x center */
- int y0; /* y center */
- RGBColor rgb; // for > 8 bits
- int x;
- int maxy; // was int, was double
- } spherestruct;
-
- #define MAXSCREENS 4 // maximum of 4 screens (lets not go crazy!)
- unsigned short RangedRdm( unsigned short min, unsigned short max );
- #define random() RangedRdm(0, 32767)
- RGBColor RandomRGBColor(void);
- RGBColor RandomIndexColor(short screenDepth);
-
- static spherestruct spheres[MAXSCREENS];
-
- void initsphere(int screen, Rect *theRect);
- void drawsphere(int screen, int screenDepth);
-
- void
- initsphere(int screen, Rect *theRect)
- {
- spherestruct *ss = &spheres[screen];
-
- ss->r = *theRect;
-
- ss->width = (theRect->right - theRect->left); //.width;
- ss->height = (theRect->bottom - theRect->top); //.height;
-
- ss->x = ss->radius = 0;
- }
-
- void
- drawsphere(int screen, int screenDepth)
- {
- spherestruct *ss = &spheres[screen];
- register short y;
- register short test;
- short maxRadius;
-
- if (ss->x >= ss->radius) {
- #ifndef LIMIT_RADIUS
- ss->radius = random() % (MIN(ss->width / 2, ss->height / 2)-1) + 1;
-
- ss->x0 = random() % ss->width;
- ss->y0 = random() % ss->height;
- ss->x = -ss->radius;
- #else // limit the radius ... sqrt() sucks
- maxRadius = MIN( 127, (ss->width/2) ); // see comment below to see why 127
- maxRadius = MIN( maxRadius, (ss->height/2) );
-
- // was silly to have a minimum of 1 as a sphere radius!
- ss->radius = RangedRdm(2, maxRadius); // sqrt() here fails when the high bit is set!
- ss->x0 = RangedRdm(0, ss->width-1);
- ss->y0 = RangedRdm(0, ss->height-1);
- ss->x = -ss->radius;
- #endif
-
-
- // can't we do this later?
- if (screenDepth > 8)
- ss->rgb = RandomRGBColor();
- //ss->color = random() % (1 << screenDepth ); // pick a random color
- else if (screenDepth > 1)
- ss->rgb = RandomIndexColor( screenDepth);
- }
-
- ss->maxy = SQRT( (ss->radius * ss->radius) - (ss->x * ss->x) );
-
-
- // if (errno == 33) SysBeep(0);
-
- // if this vertical line is onscreen, draw it
- // do I need to worry about this test?
- if ( ss->r.left + ss->x0 + ss->x >= ss->r.left &&
- ss->r.left + ss->x0 + ss->x <= ss->r.right) {
- ForeColor(blackColor);
- MoveTo( ss->r.left + ss->x0 + ss->x, ss->r.top + ss->y0 - ss->maxy);
- LineTo( ss->r.left + ss->x0 + ss->x, ss->r.top + ss->y0 + ss->maxy);
- }
-
-
- if (screenDepth > 1)
- RGBForeColor( &ss->rgb);
- else
- ForeColor( whiteColor);
-
-
- for (y = -ss->maxy; y <= ss->maxy; y++) {
- register short X, Y;
-
- X = ss->r.left + ss->x + ss->x0;
- Y = ss->r.top + y + ss->y0;
-
- if ( (random() % (ss->radius * NR)) <=
- (NX * ss->x + NY * y + NZ *
- SQRT(ss->radius * ss->radius - ss->x * ss->x - y * y) ) )
-
- // XDrawPoint(dsp, win, Scr[screen].gc, ss->x + ss->x0, y + ss->y0);
- #if 0
- MoveTo(X, Y);
- Line(0 , 0);
- #else
- #if 0
- if ( Y > ss->r.bottom) // if we're past the bottom, this vert line is done
- break;
- if ( Y < ss->r.top) // we not at the top ... continue the loop
- continue;
- #endif
-
- if ( X >= ss->r.left && X <= ss->r.right) { // are we onscreen?
- if (screenDepth > 1)
- SetCPixel(X, Y, &ss->rgb);
- else {
- MoveTo(X, Y);
- LineTo(X, Y);
- //SysBeep(0); // fix this!!
- }
- }
- #endif
- }
- ss->x++;
- }
-
- RGBColor
- RandomIndexColor(short screenDepth) {
- short i;
- RGBColor rgb;
-
- i = RangedRdm(0, (1 << screenDepth) - 2 ); // highest color == black
- Index2Color(i, &rgb);
- return rgb;
- }
-
- RGBColor
- RandomRGBColor(void) {
- RGBColor rColor;
- short chance;
-
- chance = RangedRdm(0, 5);
-
- switch( chance) {
- case 0: // equal randomness
- rColor.red = RangedRdm(0, 65535);
- rColor.blue = RangedRdm(0, 65535);
- rColor.green = RangedRdm(0, 65535);
- break;
- case 1: // more red
- rColor.red = RangedRdm(32767, 65535);
- rColor.blue = RangedRdm(0, 65535);
- rColor.green = RangedRdm(0, 65535);
- case 2: // more blue
- rColor.red = RangedRdm(0, 65535);
- rColor.blue = RangedRdm(32767, 65535);
- rColor.green = RangedRdm(0, 65535);
- case 3: // more green
- rColor.red = RangedRdm(0, 65535);
- rColor.blue = RangedRdm(0, 65535);
- rColor.green = RangedRdm(32767, 65535);
-
- default: // brighter hues of any color
- {
- HSVColor hColor;
-
- hColor.hue = (SmallFract)(RangedRdm(0, 65535) );
- hColor.saturation = (SmallFract)RangedRdm( 49150, 65535);
- hColor.value = (SmallFract) RangedRdm( 49150, 65535);
- HSV2RGB( &hColor, &rColor);
- }
- }
- return rColor;
- }
-
-
-
- // this is from the Think C reference code example ...
- unsigned short RangedRdm( unsigned short min, unsigned short max )
- /* assume that min is less than max */
- {
- // uh ... not this isn't quite right - it's between 0 and 65535, not 65536
- // -----------------------------------------vvvvv
- unsigned qdRdm; /* treat return value as 0-65536 */
- long range, t;
-
- // just to be safe, I'll put this here
- if (min > max) DebugStr("\pMin greater then Max in RangedRdm");
-
- qdRdm = Random();
- range = max - min;
- // max - min gives us the the difference between max and min ... that is
- // not inclusive. It gives us { min <= range < max }
- // so we never see that max number!!
- range++;
- t = ((long)qdRdm * range) / 65536; /* now 0 <= t <= range */
- return( t+min );
- }
-
-